package asteroids.model;

import java.util.Random;
import asteroids.Vector;
import be.kuleuven.cs.som.annotate.*;

/**
 * @version	1.0
 * @author 	Ewoud Van Esch & Jomi Verwimp
 */
public class Asteroid extends GameObject{

	/**
	 * @param 	xPos
	 * @param 	yPos
	 * @param 	xVel
	 * @param	yVel
	 * @param 	radius
	 * 
	 * @effect	| super(xPos, yPos, xVel, yVel, radius, (4/3)*Math.PI*Math.pow(radius,3)*2.65E12)
	 * @effect	| this.random = new Random()
	 */
	public Asteroid(double xPos, double yPos, double xVel, double yVel, double radius) {
		super(xPos, yPos, xVel, yVel, radius, (4/3)*Math.PI*Math.pow(radius,3)*2.65E12);
		this.random = new Random();
	}
	
	/**
	 * @param xPos
	 * @param yPos
	 * @param xVel
	 * @param yVel
	 * @param radius
	 * @param random
	 * 
	 * @effect	| super(xPos, yPos, xVel, yVel, radius, (4/3)*Math.PI*Math.pow(radius,3)*2.65E12)
	 * @post	| new.getRandom() == random
	 */
	public Asteroid(double xPos, double yPos, double xVel, double yVel, double radius, Random random) {
		super(xPos, yPos, xVel, yVel, radius, (4/3)*Math.PI*Math.pow(radius,3)*2.65E12);
		this.random = random;
	}
	
	/**
	 * @return	random
	 */
	@Basic
	public Random getRandom() {
		return random;
	}
	
	private final Random random;
	
	/**
	 * @effect	| spawnChildren()
	 * @effect	| getWorld().remove(this)
	 */
	public void terminate() {
		spawnChildren();
		getWorld().remove(this);
	}
	
	/**
	 * @effect	| if(getWorld() != null && getRadius() >= 30)
	 * 		    | 	then(double randDir = new Vector(getRandom()).getVectorAngle()
	 * 			|  		 double oldVel =  1.5*this.getVelocity().getNorm()
	 *          |		 Vector newVel = new Vector(oldVel*Math.cos(randDir), oldVel*Math.sin(randDir))
	 *          |		 getWorld().add(new Asteroid(getPosition().getX() + 0.5*getRadius(), getPosition().getY(), newVel.getX(), newVel.getY(), 0.5*getRadius())
	 *			|		 getWorld().add(new Asteroid(getPosition().getX() - 0.5*getRadius(), getPosition().getY(), -newVel.getX(), -newVel.getY(), 0.5*getRadius())	
	 */
	public void spawnChildren() {
		if ( (getWorld() != null) && (getRadius() >= 30) ) {
			double randDir = new Vector(getRandom()).getVectorAngle();
			double oldVel =  1.5*this.getVelocity().getNorm();
			Vector newVel = new Vector(oldVel*Math.cos(randDir), oldVel*Math.sin(randDir));
			Asteroid asteroid1 = new Asteroid(getPosition().getX() + 0.5*getRadius(), getPosition().getY(), newVel.getX(), newVel.getY(), 0.5*getRadius());
			Asteroid asteroid2 = new Asteroid(getPosition().getX() - 0.5*getRadius(), getPosition().getY(), -newVel.getX(), -newVel.getY(), 0.5*getRadius());
			getWorld().add(asteroid1);
			getWorld().add(asteroid2);
		}
	}
	
	/**
	 * @param	other
	 * 
	 * @effect	| other.resolve(this)
	 */
	@Override
	public void collide(WorldObject other) {
		other.resolve(this);
	}

	/**
	 * @param	other
	 * 
	 * @effect	| other.terminate()
	 */
	@Override
	public void resolve(Ship other) {
		other.terminate();
	}

	/**
	 * @param	other
	 * 
	 * @effect	| bounceOff(other)
	 */
	@Override
	public void resolve(Asteroid other) {
		bounceOff(other);
	}

	/**
	 * @param	other
	 * 
	 * @effect	| this.terminate()
	 * @effect	| other.terminate()
	 */
	@Override
	public void resolve(Bullet other) {
		this.terminate();
		other.terminate();
	}

	/**
	 * @param	hb
	 * 
	 * @effect	| bounceHorBound()
	 */
	@Override
	public void resolve(HorBound hb) {
		bounceHorBound();
	}

	/**
	 * @param	vb
	 * 
	 * @effect	| bounceVerBound()
	 */
	@Override
	public void resolve(VerBound vb) {
		bounceVerBound();
	}

}
